#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Material>
#include <osg/PositionAttitudeTransform>
#include <osg/Group>
#include <osg/Vec4>
#include <random>

float rand_0_5_to_3()
{
    static std::mt19937                          rng{ std::random_device{}() };
    static std::uniform_real_distribution<float> dist(0.5, 3.0);
    return dist(rng);
}

float rand_0_5()
{
    static std::mt19937                          rng{ std::random_device{}() };
    static std::uniform_real_distribution<float> dist(0.5, 1.0);
    return dist(rng);
}
/**
    实现多头牛的展示，并配置不同的颜色位置和角度
*/
using namespace osg;
using namespace std;
// 随机颜色生成器
Vec4 rndColor() {
    static std::mt19937 rng(0);
    static uniform_real_distribution<float> u{ 0.2f, 1.0f };
    return Vec4f{ u(rng), u(rng), u(rng), 1.0f };
}

int main(int argc, char** argv) {
    osg::setNotifyLevel(osg::INFO);
    osg::DisplaySettings::instance()->setMinimumNumStencilBits(8);
    osg::DisplaySettings::instance()->setNumMultiSamples(4);
    // 1. 只读一次原始牛
    osg::ref_ptr<osg::Node> originalCow = osgDB::readNodeFile("D:/learn/osg-learning/cow.osgt");
    if (!originalCow)
    {
        osg::notify(osg::FATAL) << "cow.osg not found\n";
        return 1;
    }

    // 2. 准备根节点
    osg::ref_ptr<osg::Group> root = new osg::Group;

    const unsigned int N = 10;               // 想要几头牛
    const float        R = 40.0f;           // 摆放半径
    for (unsigned int i = 0; i < N; ++i)
    {
        // 2-a 颜色材质
        osg::ref_ptr<osg::Material> mat = new osg::Material;
        Vec4 color = rndColor();
        mat->setDiffuse(osg::Material::FRONT_AND_BACK, color);
        mat->setAmbient(osg::Material::FRONT_AND_BACK, color);
        mat->setColorMode(osg::Material::OFF);   // 关闭颜色追踪，只用我们给的材质

        // 2-b 位置变换
        osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform;
        float angle = 2.0f * osg::PI * i / N;
        pat->setPosition(osg::Vec3(R * cosf(angle), R * sinf(angle), 0.0f));
        pat->setAttitude(osg::Quat(osg::inDegrees(i * 15.0f), osg::Z_AXIS)); // 再转个向
        float scale = rand_0_5_to_3();
        pat->setScale(Vec3(scale, scale, scale)); 
        // 2-c 把牛“实例化”——clone 轻量节点，共享几何
        osg::ref_ptr<osg::Node> cowInstance = osg::clone(originalCow.get(), osg::CopyOp::SHALLOW_COPY);
        pat->addChild(cowInstance);

        // 2-d 把材质挂到 PAT（对子树生效）
        pat->getOrCreateStateSet()->setAttributeAndModes(mat, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);

        root->addChild(pat);
    }

    // 3. 启动查看器
    osgViewer::Viewer viewer;
    viewer.setSceneData(root);
    return viewer.run();
}